# -*- coding: utf-8 -*-
# 作者： 安智军
# @Time：2022/6/16 22:09
# @Email：1010666711@qq.com
# @File： book.py
'''
类和对象的关系
安智军自己的理解 ：类封装了很多个对象 汽车是一个类 对象是挂着车牌的那个车
对象是一个实体的对象

图书管理系统有啥  管理员  图书：图书编号 图书名称 位置 价格
对书的操作 系统管理员查看所有的书，书的管理 curd 增修读删（俗称增删改查）
2天内实现对书的增删改查
'''
import os
import pickle


class Book(object):

    def __init__(self, num, name, loc, price):
        self.num = num
        self.name = name
        self.loc = loc
        self.price = price

    def __str__(self):
        '''
        自定义print输入的格式
        '''
        '''
        __str__ 方法说明
        1. __str__方法定义
        __ str __：
        在python中 使用print输出对象变量时候，默认情况下
        会输出这个变量引用的对象是由哪一个类创建的对象以及在内存中的地址
        如果在开发中，希望使用print输出变量的时候，能够打印自定义内容
        就可以利用__str__这个内置的方法了

        :return:
        '''
        # print(help('__str__'))
        return f'序号：{self.num}\t{self.name}\t{self.loc}\t{self.price}'


class BookMange(object):
    book_list = []  # 存放书的列表

    # 保存图书
    def __init__(self):
        # __init__ 对象在初始化时被执行
        print('__init__ is running')
        '''加载文件到内存'''
        # 怎么加载 如何加载 pickle 包
        # pickle.dump(self.book_list,open('book.data','wb')) # 把对象保存在文件 就是序列化
        '''
        第一开始执行的时候文件不存在 怎么办？ 
        异常处理：
        1、加判断 事前处理
        2、异常处理 事后处理
        '''
        # 方法一 加判断 避免异常
        # 加判断 使用os 模块 判断文件是否存在
        if os.path.isfile('book.data'):  # def isfile(path: AnyPath) -> bool: ... 返回布尔值
            self.book_list = pickle.load(open('book.data', 'rb'))  # 把文件中的内容加载到内存 就是反序列化
        else:  # 文件不存在 创建文件
            pickle.dump(self.book_list, open('book.data', 'wb'))  # 把对象保存在文件 就是序列化


        # 方法二 异常处理 使用try 捕获异常
        # try:
        #     self.book_list = pickle.load(open('book.data', 'rb'))
        # # except Exception as e:  # 捕获异常  Exception 所有的异常
        # except FileNotFoundError as e:  # 捕获具体的衣长
        #     print('异常的内容是：{}不存在'.format(e))
        #     print('文件不存在')
        #     # 创建文件(文件不存在则创建文件)
        #     pickle.dump(self.book_list, open('book.data', 'wb'))
        #     print('文件创建成功')

    def show_book(self):
        '''
        展示所有图书
        :return:
        '''
        # print(self.book_list) # [<dev_01_day.book.Book object at 0x0000020489DD8788>, <dev_01_day.book.Book object at 0x0000020489F2AB48>]
        for book in self.book_list:
            print(book)

    # def add_book(self, book: Book):  # book:Book 冒号后面：是类型 book是变量 变量的类型是Book类型 比如s:str s是个字符串
    def add_book(self, book: Book):  # book:Book 冒号后面：是类型 book是变量 变量的类型是Book类型 比如s:str s是个字符串

        '''
        添加图书
        :param book:
        :return:
        '''
        self.book_list.append(book)

    # 获取最后一本书的id
    # @property  # 把方法变为一个属性
    def last_book_id(self):
        if self.book_list:
            return self.book_list[-1].num
        return 0

    # s：str 讲解 s的类型是个字段串 就是申明类型 str下面有很多方法 s.字符串的各种方法
    def f1(self, s: str):
        s.split(',')

    def clean_data(self):
        '''
        清空数据
        '''
        self.book_list = []
        print('数据清空成功请退出后生效 ')
        return self.book_list

    def save(self):
        '''
        保存数据
        '''
        pickle.dump(self.book_list, open('book.data', 'wb'))  # 把对象保存在文件 就是序列化

    # 删除图书
    def del_book_by_name(self,name:str):
        '''
        通过书名删除图书
        :return:
        '''

        for i,book in enumerate(self.book_list):
            if book.name == name:
                # del self.book_list[i]  # 根据下标删除
                self.book_list.remove(book)
                print('删除成功，图书：{}删除成功'.format(name))

                break
            else:
                print('删除失败，图书：{}不存在,请核对检查'.format(name))


    def __del__(self):
        ''' 加载文件到内存'''
        # 对象在被销毁时执行
        print('__del__ is running')
        # 保存文件
        pickle.dump(self.book_list, open('book.data', 'wb'))  # 把对象保存在文件 就是序列化


if __name__ == '__main__':
    book = Book(1, '变成狼车', '2号架4层', '15元')
    # print(book.name)
    print(book)
    # print(f'{book.name}\t{book.loc}\t{book.price}')
